home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Messaging / MssgSI.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  27.4 KB  |  856 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MssgSI.cpp
  3.  
  4.     Contains:    Implementation of Mac specific DefaultAccessorSI class.
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <38>     10/4/95    jpa        Added missing ODVolatiles [1285799]
  13.         <37>    25/09/95    NP        1979071: Check results of operator new.
  14.         <36>     9/11/95    NP        1272294: Messaging code cleanup. 1283174:
  15.                                     Mem leak plugs.
  16.         <35>      9/8/95    jpa        eeh: 1269501: Lowercase before string
  17.                                     comparisons.
  18.         <34>     8/23/95    NP        1276287: Move constant kODAppShell.
  19.         <33>     8/18/95    NP        1274946: Add kODErrCantCountFromLists.
  20.         <32>     8/16/95    eeh        1277001: remove ContainerRepresentsPart
  21.         <31>      8/7/95    NP        1275104: Exception safety.
  22.         <30>      8/3/95    RR        #1257260: Collapse B classes. Remove
  23.                                     somInit methods. Don't call IsInitialized
  24.                                     or SubclassResponsibility
  25.         <29>      8/1/95    eeh        1265319: accept NULL as representing part
  26.         <28>     7/27/95    eeh        1204615: call TrySwapToRootPart for 'exmn'
  27.         <27>     7/21/95    eeh        1266906: fix CallCountProc; 1262143: call
  28.                                     ODDisposeAppleEvent
  29.         <26>     6/30/95    JP        Release on dispose of standard part token
  30.         <25>     6/28/95    eeh        1262143: dispose AEDescs
  31.         <24>     6/27/95    NP        1263224: Remove Release call in
  32.                                     DiposeTokenProc for now.
  33.         <23>     6/26/95    NP        1262143: Dispose copy of Apple event made
  34.                                     in CallEventHandler
  35.         <22>     6/22/95    NP        1261984: Don't delete token after passing
  36.                                     it to ODNameResolver::DisposeToken!
  37.         <21>     6/20/95    NP        Removed dangerous comment.
  38.         <20>     6/19/95    eeh        1246443: add PartFrameFromStandardPartToken
  39.                                     etc.
  40.         <19>     6/13/95    eeh        1257105: fix string compare
  41.         <18>      6/7/95    eeh        1250399: implement default CompareProc
  42.         <17>     5/21/95    NP        1248898: GetUserToken, ODDescToAEDesc, etc.
  43.                                     recipe change.
  44.         <16>     5/18/95    eeh        1250061: implement countproc
  45.         <15>     4/28/95    eeh        1244258: IsValid->CheckValid; SOM_TRY
  46.                                     around it
  47.         <14>     4/27/95    NP        1244309-Default count proc returns -1 only
  48.                                     if the part is equal to kODAppShell.
  49.         <13>     4/27/95    eeh        1240648: call somSelf->IsValid
  50.         <12>     4/25/95    NP        1186795, 1237220, 1240571: Fixed whose
  51.                                     clauses by allowing swapping in count proc.
  52.         <11>     4/14/95    NP        1239651: Include SEPriv.h. 1238022: default
  53.                                     event handler was almost always returning
  54.                                     noErr.
  55.         <10>      4/7/95    eeh        1236842: call TrySwapToRootPart
  56.          <9>     3/24/95    eeh        1232249: remove frame from
  57.                                     DEFAULT_ACCESSOR_PARAMS
  58.          <8>     3/21/95    JP        1192027: Include ODRgstry & change some
  59.                                     constant names
  60.          <7>     3/13/95    NP        1226003: Remove GetContainingFrame from the
  61.                                     API. Use GetContextFromToken.
  62.          <6>      3/2/95    eeh        1214783: cleanup related to lists
  63.          <5>     2/22/95    eeh        1222901: look for StandardPartToken
  64.          <4>     2/21/95    eeh        1214783: add WildcardFromList accessor;
  65.                                     change accessor API
  66.          <3>      2/3/95    eeh        1217393: use new ODDesc etc
  67.          <2>     1/27/95    NP        1213948: New classes for ODDesc et al.
  68.          <1>     1/25/95    eeh        #1214783-first check-in as unique file.
  69.          <3>     1/11/95    NP        #1188520-Pass real ODPart to parts.
  70.          <2>      1/9/95    NP        1194880: MssgSI name changes.
  71.          <1>    11/15/94    NP        first checked in
  72.          <7>     9/23/94    NP        1188520-Pass the real ODPart descendent to
  73.                                     the SemanticInterface extension rather than
  74.                                     the ODPartWrapper.
  75.          <6>      9/9/94    NP        1185851: implement scripting. 1184040: API
  76.                                     changes.
  77.          <5>      9/9/94    jpa        Removed call to parent in Release, at
  78.                                     Nick's request. [1185656]
  79.          <4>      7/8/94    NP        Initialize fHelper field.
  80.          <3>      7/8/94    NP        Fixed bugs, implemented coercion handlers,
  81.                                     fixed initialization.
  82.          <2>      7/5/94    NP        Filled in CallEventHandler.
  83.          <1>      7/1/94    NP        first checked in
  84.  
  85.     To Do:
  86.     In Progress:
  87. */
  88.  
  89.  
  90. #ifndef _EXCEPT_
  91. #include "Except.h"
  92. #endif
  93.  
  94. #ifndef _SEPRIV_
  95. #include "SEPriv.h"
  96. #endif
  97.  
  98. #ifndef _DFLTACS_
  99. #include <DfltAcs.h>
  100. #endif
  101.  
  102. #ifndef _ODDESUTL_
  103. #include <ODDesUtl.h>
  104. #endif
  105.  
  106. #ifndef SOM_ODOSLToken_xh
  107. #include "ODOSLTkn.xh"
  108. #endif
  109.  
  110. #ifndef SOM_ODAppleEvent_xh
  111. #include "ODAplEvt.xh"
  112. #endif
  113.  
  114. #ifndef _ODREGISTRY_
  115. #include "ODRgstry.xh"
  116. #endif
  117.  
  118. #ifndef _SEUTILS_
  119. #include <SEUtils.h>
  120. #endif
  121.  
  122. #ifndef SOM_ODNameResolver_xh
  123. #include <NamRslvr.xh>
  124. #endif
  125.  
  126. #ifndef _PASCLSTR_
  127. #include <PasclStr.h>
  128. #endif
  129.  
  130. #define VARIABLE_MACROS
  131. #define DefaultAccessorSI_Class_Source
  132. #include <MssgSI.xih>
  133.  
  134. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  135. #include <StdDefs.xh>
  136. #endif
  137.  
  138. #pragma segment DefaultAccessorSI
  139.  
  140. //------------------------------------------------------------------------------
  141. // function prototypes
  142. //------------------------------------------------------------------------------
  143.  
  144. static void ResolveDesc( Environment *ev, ODPart* part, ODSession* session,
  145.         ODOSLToken* obj, AEDesc* data );
  146. static short BitwiseCompare( AEDesc* data1, AEDesc* data2 );
  147. static short CompareDescs( AEDesc* data1, AEDesc* data2 );
  148. //static ODBoolean ContainerRepresentsPart( Environment* ev,
  149. //        ODNameResolver* resolver, ODOSLToken* container );
  150.  
  151. //------------------------------------------------------------------------------
  152. // DefaultAccessorSI::InitCPlusSemanticInterface
  153. //------------------------------------------------------------------------------
  154.  
  155. SOM_Scope void  SOMLINK DefaultAccessorSIInitCPlusSemanticInterface(DefaultAccessorSI *somSelf, Environment *ev,
  156.         ODPart* base,
  157.         SIHelperAbs* helper,
  158.         ODSession* session)
  159. {
  160.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  161.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSIInitCPlusSemanticInterface");
  162.     
  163.     SOM_TRY
  164.         somSelf->InitSemanticInterface(ev, base, session);
  165.     SOM_CATCH_ALL
  166.     SOM_ENDTRY
  167. }
  168.  
  169. //------------------------------------------------------------------------------
  170. // DefaultAccessorSI::somUninit
  171. //------------------------------------------------------------------------------
  172.  
  173. SOM_Scope void  SOMLINK DefaultAccessorSIsomUninit(DefaultAccessorSI *somSelf)
  174. {
  175.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  176.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSIsomUninit");
  177.  
  178.     DefaultAccessorSI_parents_somUninit(somSelf);
  179. }
  180.  
  181. //------------------------------------------------------------------------------
  182. // DefaultAccessorSI::InitSemanticInterface
  183. //------------------------------------------------------------------------------
  184.  
  185. SOM_Scope void  SOMLINK DefaultAccessorSIInitSemanticInterface(DefaultAccessorSI *somSelf, Environment *ev,
  186.         ODPart* base,
  187.         ODSession* session)
  188. {
  189.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  190.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSIInitSemanticInterface");
  191.  
  192.     _fSession = session;
  193.  
  194.     DefaultAccessorSI_parent_ODSemanticInterface_InitSemanticInterface(somSelf, ev, base, session);
  195. }
  196.  
  197. //------------------------------------------------------------------------------
  198. // DefaultAccessorSI::GetSIHelper
  199. //------------------------------------------------------------------------------
  200.  
  201. SOM_Scope SIHelperAbs*  SOMLINK DefaultAccessorSIGetSIHelper(DefaultAccessorSI *somSelf, Environment *ev)
  202. {
  203.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  204.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSIGetSIHelper");
  205.  
  206.     return kODNULL;            // was _fHelper;
  207. }
  208.  
  209. //------------------------------------------------------------------------------
  210. // DefaultAccessorSI::CallEventHandler
  211. //------------------------------------------------------------------------------
  212.  
  213. SOM_Scope void  SOMLINK DefaultAccessorSICallEventHandler(DefaultAccessorSI *somSelf, Environment *ev,
  214.         ODPart* thePart,
  215.         ODAppleEvent* theODAppleEvent,
  216.         ODAppleEvent* reply)
  217. {
  218.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  219.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallEventHandler");
  220.  
  221.     OSErr error;            //= errAEEventNotHandled;
  222.  
  223.     SOM_TRY
  224.         somSelf->CheckValid(ev);
  225.  
  226.         AppleEvent realMessage;
  227.     
  228.         THROW_IF_ERROR( ODDescToAEDesc(theODAppleEvent, &realMessage) );
  229.  
  230.             AEEventClass eventClass = (AEEventClass)GetSLongAttr(
  231.                     &realMessage, keyEventClassAttr);
  232.             AEEventID eventID = (AEEventID)GetSLongAttr(
  233.                     &realMessage, keyEventIDAttr);
  234.     
  235.             EventHandlerProc ehp;
  236.     
  237.             if ( (eventClass == kAECoreSuite) && (eventID == kAEGetData) )
  238.                 ehp = HandleGetData;
  239.             else if ( (eventClass == kAECoreSuite) && (eventID == kAESetData) )
  240.                 ehp = HandleSetData;
  241.             else
  242.                 ehp = kODNULL;
  243.     
  244.             if ( ehp )
  245.                 error = (*ehp)( ev, thePart, theODAppleEvent, reply, _fSession );
  246.             else
  247.                 error = errAEEventNotHandled;
  248.  
  249.         ODDisposeAppleEvent(&realMessage);
  250.  
  251.         THROW_IF_ERROR( error );
  252.     SOM_CATCH_ALL
  253.     SOM_ENDTRY
  254. }
  255.  
  256. //------------------------------------------------------------------------------
  257. // DefaultAccessorSI::CallCoercionHandler
  258. //------------------------------------------------------------------------------
  259.  
  260. SOM_Scope void  SOMLINK DefaultAccessorSICallCoercionHandler(DefaultAccessorSI *somSelf, Environment *ev,
  261.         ODPart* thePart,
  262.         ODDesc* theODDesc,
  263.         ODDescType toType,
  264.         ODDesc* result)
  265. {
  266.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  267.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallCoercionHandler");
  268.  
  269.     OSErr error = errAECoercionFail;//= CallCoercionHandler(thePart, theODDesc, toType, result);
  270.     SOM_TRY
  271.         somSelf->CheckValid(ev);
  272.         WARN( "DefaultAccessorSICallCoercionHandler not implemented" );
  273.         THROW( error );
  274.     SOM_CATCH_ALL
  275.     SOM_ENDTRY
  276. }
  277.  
  278. //------------------------------------------------------------------------------
  279. // DefaultAccessorSI::CallObjectAccessor
  280. //------------------------------------------------------------------------------
  281.  
  282. SOM_Scope void  SOMLINK DefaultAccessorSICallObjectAccessor(DefaultAccessorSI *somSelf, Environment *ev,
  283.         ODPart* thePart,
  284.         ODDescType desiredClass,
  285.         ODOSLToken* container,
  286.         ODDescType containerClass,
  287.         ODDescType form,
  288.         ODDesc* selectionData,
  289.         ODOSLToken* value)
  290. {
  291.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  292.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallObjectAccessor");
  293.  
  294.     OSErr error;
  295.     SOM_TRY
  296.         somSelf->CheckValid(ev);
  297.  
  298.         ODDesc* userTokenWrapper = kODNULL;
  299.     
  300.         AEDesc realToken = NULL_DESCRIPTOR_DEFINITION;
  301.         DescType containerType = typeNull;
  302.         ODNameResolver* resolver = _fSession->GetNameResolver(ev);
  303.     
  304.         ASSERT(resolver->IsODToken( ev, container ), kODTrue);
  305.         userTokenWrapper = resolver->GetUserToken(ev, container);
  306.         THROW_IF_ERROR(ODDescToAEDesc(userTokenWrapper, &realToken ));
  307.         containerType = realToken.descriptorType;
  308.             
  309.         error = errAEAccessorNotFound;
  310.         PartAccessorProc pac;
  311.     
  312.         if ( (containerType == kODStandardPartTokenType) 
  313.                 || CanBeStandardPartToken( &realToken ) )
  314.             pac = GetWildcardFromPart;
  315.         else if ( containerType == typeAEList )
  316.             pac = GetWildcardFromList;
  317.         else if ( (desiredClass == cPart) && (containerType == typeNull) )
  318.             pac = GetPartFromNULL;
  319.         else if ( (desiredClass == cProperty) && (containerType == typeNull) )
  320.             pac = GetPropFromNULL;
  321.         else if ( (thePart == kODAppShell) && ((containerType == typeNull)
  322.                 || (containerType == typeObjectBeingExamined)) )
  323.             pac = TrySwapToRootPart;
  324.         else
  325.             pac = kODNULL;
  326.     
  327.         if ( pac )
  328.         {
  329.             // We have to pass value as an ODOSLToken* in case the accessor
  330.             // needs to call CreateSwapToken on it.
  331.     
  332.             error = (*pac)( ev, thePart, desiredClass, &realToken,
  333.                     containerClass, form, selectionData, value,
  334.                     _fSession );
  335.         }
  336.         (void)AEDisposeDesc( &realToken );
  337.         THROW_IF_ERROR( error );
  338.  
  339.     SOM_CATCH_ALL
  340.     SOM_ENDTRY
  341. }
  342.  
  343. //------------------------------------------------------------------------------
  344. // DefaultAccessorSI::CallPredispatchProc
  345. //------------------------------------------------------------------------------
  346.  
  347. SOM_Scope void  SOMLINK DefaultAccessorSICallPredispatchProc(DefaultAccessorSI *somSelf, Environment *ev,
  348.         ODPart* thePart,
  349.         ODAppleEvent* theODAppleEvent,
  350.         ODAppleEvent* reply)
  351. {
  352.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  353.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallPredispatchProc");
  354.  
  355.     OSErr error = errAEEventNotHandled;//= CallPredispatchProc(thePart, theODAppleEvent, reply);
  356.     SOM_TRY
  357.         somSelf->CheckValid(ev);
  358.         WARN( "DefaultAccessorSICallPredispatchProc not implemented" );
  359.         THROW_IF_ERROR( error );
  360.     SOM_CATCH_ALL
  361.     SOM_ENDTRY
  362. }
  363.  
  364. //------------------------------------------------------------------------------
  365. // DefaultAccessorSI::CallCompareProc
  366. //------------------------------------------------------------------------------
  367.  
  368.  
  369. SOM_Scope void  SOMLINK DefaultAccessorSICallCompareProc(DefaultAccessorSI *somSelf, Environment *ev,
  370.         ODPart* thePart,
  371.         ODDescType oper,
  372.         ODOSLToken* obj1,
  373.         ODOSLToken* obj2,
  374.         ODBoolean* result)
  375. {
  376.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  377.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallCompareProc");
  378.  
  379.     OSErr error = errAEEventNotHandled;
  380.     AEDesc obj1AsData, obj2AsData, tmpDesc;
  381.  
  382.     SOM_TRY
  383.         somSelf->CheckValid(ev);
  384.  
  385.         obj1AsData.dataHandle = obj2AsData.dataHandle = tmpDesc.dataHandle =
  386.                 kODNULL;
  387.         ODNameResolver* resolver = _fSession->GetNameResolver(ev);
  388.         ResolveDesc( ev, thePart, _fSession, obj1, &obj1AsData );
  389.         ResolveDesc( ev, thePart, _fSession, obj2, &obj2AsData );
  390.         
  391.         short compResult;
  392.         if ( obj1AsData.descriptorType == obj2AsData.descriptorType )
  393.         {
  394.             compResult = CompareDescs( &obj1AsData, &obj2AsData );
  395.         }
  396.         else if ( !AECoerceDesc( &obj1AsData, obj2AsData.descriptorType,
  397.                 &tmpDesc ) )
  398.         {
  399.             compResult = CompareDescs( &tmpDesc, &obj2AsData );
  400.             (void)AEDisposeDesc( &tmpDesc );
  401.         }
  402.         else if ( !AECoerceDesc( &obj2AsData, obj1AsData.descriptorType,
  403.                 &tmpDesc ) )
  404.         {
  405.             compResult = CompareDescs( &tmpDesc, &obj1AsData );
  406.             (void)AEDisposeDesc( &tmpDesc );
  407.         }
  408.         (void)AEDisposeDesc( &obj1AsData );
  409.         (void)AEDisposeDesc( &obj2AsData );
  410.         error = noErr;
  411.         
  412.         switch( oper )
  413.         {
  414.             case kAEEquals:
  415.                 *result = compResult == 0;
  416.                 break;
  417.             case kAEGreaterThan:
  418.                 *result = compResult > 0;
  419.                 break;
  420.             case kAELessThan:
  421.                 *result = compResult < 0;
  422.                 break;
  423.             case kAEGreaterThanEquals:
  424.                 *result = compResult >= 0;
  425.                 break;
  426.             case kAELessThanEquals:
  427.                 *result = compResult <= 0;
  428.                 break;
  429.             default:
  430.                 error = -2;            // <eeh> kAEInvalidCompare or something
  431.         }
  432.         THROW_IF_ERROR( error );
  433.     SOM_CATCH_ALL
  434.         (void)AEDisposeDesc( &obj1AsData );
  435.         (void)AEDisposeDesc( &obj2AsData );
  436.         (void)AEDisposeDesc( &tmpDesc );
  437.     SOM_ENDTRY
  438. }
  439.  
  440. //------------------------------------------------------------------------------
  441. // DefaultAccessorSI::CallCountProc
  442. //------------------------------------------------------------------------------
  443.  
  444. SOM_Scope void  SOMLINK DefaultAccessorSICallCountProc(DefaultAccessorSI *somSelf, Environment *ev,
  445.         ODPart* thePart,
  446.         ODDescType desiredType,
  447.         ODDescType containerClass,
  448.         ODOSLToken* container,
  449.         ODSLong* result)
  450. {
  451.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  452.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallCountProc");
  453.  
  454.     // ASK TO SWAP TO SEE IF ROOT PART CAN HANDLE THIS. CallCountProc in
  455.     //    NamRslvr.cpp WILL SWAP TO THE ROOT PART IF kODCountProcSwapValue IS
  456.     //    RETURNED AND THE PART IS THE SHELL. THIS IS NOT THAT GREAT, SEEING AS
  457.     //    THE DEFAULT SEMANTIC INTERFACE SHOULD REALLY BE DETERMINING WHAT THE
  458.     //    PROPER PART TO SWAP TO IS.
  459.     SOM_TRY
  460.         somSelf->CheckValid(ev);
  461.         ODNameResolver* resolver = _fSession->GetNameResolver(ev);
  462.  
  463.         if ( thePart == kODAppShell)
  464.             *result = kODCountProcSwapValue;
  465.         else if ( resolver->IsODToken( ev, container ) )
  466.         {
  467.             ODError error = noErr;
  468.             ODDesc* tmpToken = resolver->GetUserToken(ev, container);
  469.             switch( tmpToken->GetDescType(ev) )
  470.             {
  471.                 case typeAEList:
  472.                     error = kODErrCantCountFromLists;
  473.                     break;
  474.                 case kODStandardPartTokenType:
  475.                 // (NULL token is not acceptable here)
  476.                 // <eeh> putting NULL back in because this breaks "every part
  477.                 // whose" when the root isn't scriptable.
  478.                 case typeNull:    
  479.                     // do the count;
  480.                     break;
  481.                 default:
  482.                 {
  483.                     AEDesc token;
  484.                     THROW_IF_ERROR( ODDescToAEDesc( tmpToken, &token ) );
  485.                     if ( !CanBeStandardPartToken( &token ) )
  486.                         error = errAEEventNotHandled;
  487.                     (void)AEDisposeDesc( &token );
  488.                 }
  489.             }
  490.             if ( error == noErr )
  491.             {
  492.                 if ( desiredType != cPart )
  493.                     *result = kODCountProcSwapValue;
  494.                 else
  495.                     *result = CountEmbeddedParts(ev, thePart);
  496.             }
  497.             else
  498.                 THROW( error );
  499.         }
  500.  
  501.     SOM_CATCH_ALL
  502.     SOM_ENDTRY
  503. }
  504.  
  505. //------------------------------------------------------------------------------
  506. // DefaultAccessorSI::CallDisposeTokenProc
  507. //------------------------------------------------------------------------------
  508.  
  509. SOM_Scope void  SOMLINK DefaultAccessorSICallDisposeTokenProc(DefaultAccessorSI *somSelf, Environment *ev,
  510.         ODPart* thePart,
  511.         ODOSLToken* unneededToken)
  512. {
  513.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  514.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallDisposeTokenProc");
  515.  
  516.     SOM_TRY
  517.         somSelf->CheckValid(ev);
  518.  
  519.         ODNameResolver* resolver = _fSession->GetNameResolver(ev);
  520.         if ( resolver->IsODToken( ev, unneededToken ) )
  521.         {
  522.             ODDesc* realTokenODDesc = resolver->GetUserToken( ev, unneededToken );
  523.             AEDesc realToken;
  524.             THROW_IF_ERROR(ODDescToAEDesc(realTokenODDesc, &realToken ));
  525.             DescType containerType = realToken.descriptorType;
  526.     
  527.             if ( containerType == typeAEList )
  528.             {
  529.                 long count;
  530.                 THROW_IF_ERROR( AECountItems( &realToken, &count ) );
  531.     
  532.                 for ( ODUShort index = 1; index <= count ; ++index )
  533.                 {
  534.                     AEDesc        oneToken;
  535.                     DescType    tokenDescType;
  536.                     THROW_IF_ERROR( AEGetNthDesc( &realToken, index, typeWildCard,
  537.                             &tokenDescType, &oneToken ) );
  538.                     ODOSLToken* subToken = new ODOSLToken();
  539.                     THROW_IF_NULL(subToken);
  540.                     subToken->InitODOSLToken(ev);
  541.                     THROW_IF_ERROR( AEDescToODDesc( &oneToken, subToken ) );
  542.                     (void)AEDisposeDesc( &oneToken );
  543.                     // <eeh> don't I need to call back into the resolver for this?
  544.                     // It could be someone else's token!
  545.                     TRY    
  546.                         resolver->DisposeToken( ev, subToken );
  547.                     //    somSelf->CallDisposeTokenProc( ev, thePart, subToken );
  548.                     CATCH_ALL
  549.                         // <eeh> just ignore errors here....I think.
  550.                     ENDTRY
  551.                 }
  552.             }
  553.             else if ( containerType == cPart )        // a standard part token
  554.             {
  555.                 ODPart*        part;
  556.                 ODFrame*    frame;
  557.                 
  558.                 PartFrameFromStandardPartToken( &realToken, &part, &frame );
  559.                 // BOTH THE PART AND FRAME DO NEED TO BE RELEASED HERE.
  560.                 ODReleaseObject( ev, part );
  561.                 ODReleaseObject( ev, frame );
  562.                 // leave error as errAEEventNotHandled so handle disposed
  563.             }
  564.     
  565.             // now dispose the *copy* we've made!  This isn't the token
  566.             // itself.  Hell, how *could* we dispose it?
  567.             (void)AEDisposeDesc( &realToken );
  568.         }
  569.  
  570.         // LET MESSAGING DISPOSE unneededToken itself.
  571.         THROW(errAEEventNotHandled);
  572.     SOM_CATCH_ALL
  573.     SOM_ENDTRY
  574. }
  575.  
  576. //------------------------------------------------------------------------------
  577. // DefaultAccessorSI::CallGetErrDescProc
  578. //------------------------------------------------------------------------------
  579.  
  580. SOM_Scope void  SOMLINK DefaultAccessorSICallGetErrDescProc(DefaultAccessorSI *somSelf, Environment *ev,
  581.         ODPart* thePart,
  582.         ODDesc** errDesc)
  583. {
  584.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  585.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallGetErrDescProc");
  586.  
  587.     OSErr error = errAEEventNotHandled;// = CallGetErrDescProc(thePart, errDesc);
  588.     SOM_TRY
  589.         somSelf->CheckValid(ev);
  590.         WARN( "DefaultAccessorSICallGetErrDescProc not implemented" );
  591.         THROW_IF_ERROR(error);
  592.     SOM_CATCH_ALL
  593.     SOM_ENDTRY
  594. }
  595.  
  596. //------------------------------------------------------------------------------
  597. // DefaultAccessorSI::CallGetMarkTokenProc
  598. //------------------------------------------------------------------------------
  599.  
  600. SOM_Scope void  SOMLINK DefaultAccessorSICallGetMarkTokenProc(DefaultAccessorSI *somSelf, Environment *ev,
  601.         ODPart* thePart,
  602.         ODOSLToken* dContainerToken,
  603.         ODDescType containerClass,
  604.         ODOSLToken* result)
  605. {
  606.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  607.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallGetMarkTokenProc");
  608.  
  609.     OSErr error = errAEEventNotHandled;// = CallGetMarkTokenProc(thePart, dContainerToken,
  610. //            containerClass, result);
  611.     SOM_TRY
  612.         somSelf->CheckValid(ev);
  613.         WARN( "DefaultAccessorSICallGetMarkTokenProc not implemented" );
  614.         THROW_IF_ERROR(error);
  615.     SOM_CATCH_ALL
  616.     SOM_ENDTRY
  617. }
  618.  
  619. //------------------------------------------------------------------------------
  620. // DefaultAccessorSI::CallMarkProc
  621. //------------------------------------------------------------------------------
  622.  
  623. SOM_Scope void  SOMLINK DefaultAccessorSICallMarkProc(DefaultAccessorSI *somSelf, Environment *ev,
  624.         ODPart* thePart,
  625.         ODOSLToken* dToken,
  626.         ODOSLToken* markToken,
  627.         ODSLong index)
  628. {
  629.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  630.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallMarkProc");
  631.  
  632.     OSErr error = errAEEventNotHandled;// = CallMarkProc(thePart, dToken, markToken, index);
  633.     SOM_TRY
  634.         somSelf->CheckValid(ev);
  635.         WARN( "DefaultAccessorSICallMarkProc not implemented" );
  636.         THROW_IF_ERROR(error);
  637.     SOM_CATCH_ALL
  638.     SOM_ENDTRY
  639. }
  640.  
  641. //------------------------------------------------------------------------------
  642. // DefaultAccessorSI::CallAdjustMarksProc
  643. //------------------------------------------------------------------------------
  644.  
  645. SOM_Scope void  SOMLINK DefaultAccessorSICallAdjustMarksProc(DefaultAccessorSI *somSelf, Environment *ev,
  646.         ODPart* thePart,
  647.         ODSLong newStart,
  648.         ODSLong newStop,
  649.         ODOSLToken* markToken)
  650. {
  651.     DefaultAccessorSIData *somThis = DefaultAccessorSIGetData(somSelf);
  652.     DefaultAccessorSIMethodDebug("DefaultAccessorSI","DefaultAccessorSICallAdjustMarksProc");
  653.  
  654.     OSErr error = errAEEventNotHandled;// = CallAdjustMarksProc(thePart, newStart, newStop, markToken);
  655.     SOM_TRY
  656.         somSelf->CheckValid(ev);
  657.         WARN( "DefaultAccessorSICallAdjustMarksProc not implemented" );
  658.         THROW_IF_ERROR(error);
  659.     SOM_CATCH_ALL
  660.     SOM_ENDTRY
  661. }
  662.  
  663. //------------------------------------------------------------------------------
  664. // Utility functions
  665. //------------------------------------------------------------------------------
  666.  
  667. static void ResolveDesc( Environment *ev, ODPart* part, ODSession* session,
  668.         ODOSLToken* obj, AEDesc* data )
  669. {
  670.     ODNameResolver* resolver = session->GetNameResolver(ev);
  671.  
  672.     if ( resolver->IsODToken( ev, obj ) )
  673.     {
  674.         AEDesc userToken, tmpDesc;
  675.         AERecord fakeReply, fakeAEVT;
  676.         userToken.dataHandle = tmpDesc.dataHandle = fakeReply.dataHandle =
  677.                 fakeAEVT.dataHandle = NULL;
  678.         ODAppleEvent* odreply, *odaevt;            ODVolatile(odaevt);
  679.         odreply = odaevt = kODNULL;                ODVolatile(odreply);
  680.  
  681.         TRY
  682.             ODDesc* userTokenHolder = resolver->GetUserToken( ev, obj );
  683.             THROW_IF_ERROR( ODDescToAEDesc( userTokenHolder, &userToken ) );
  684.             if ( userToken.descriptorType == cProperty )
  685.             {
  686.                 (void)AEDisposeDesc( &userToken );
  687.     
  688.                 THROW_IF_ERROR( ODDescToAEDesc( obj, &tmpDesc ) );
  689.                 THROW_IF_ERROR( AECreateList( NULL, 0, true, &fakeAEVT ) );
  690.                 THROW_IF_ERROR( AEPutParamDesc( &fakeAEVT, keyDirectObject,
  691.                         &tmpDesc ) );
  692.                 (void)AEDisposeDesc( &tmpDesc );
  693.                 odaevt = new ODAppleEvent();
  694.                 THROW_IF_NULL(odaevt);
  695.                 odaevt->InitODAppleEvent( ev );
  696.                 THROW_IF_ERROR( AEDescToODDesc( &fakeAEVT, odaevt ));
  697.                 (void)AEDisposeDesc( &fakeAEVT );
  698.         
  699.                 THROW_IF_ERROR( AECreateList( NULL, 0, true, &fakeReply ) );
  700.                 odreply = new ODAppleEvent();
  701.                 THROW_IF_NULL(odreply);
  702.                 odreply->InitODAppleEvent( ev );
  703.                 THROW_IF_ERROR( AEDescToODDesc( &fakeReply, odreply ));
  704.                 (void)AEDisposeDesc( &fakeReply );
  705.         
  706.                 THROW_IF_ERROR( HandleGetData( ev, part, odaevt, odreply,
  707.                         session ) );
  708.                 ODDeleteObject( odaevt );
  709.         
  710.                 THROW_IF_ERROR( ODDescToAEDesc( odreply, &fakeReply ));
  711.                 THROW_IF_ERROR( AEGetParamDesc( &fakeReply, keyDirectObject,
  712.                         typeWildCard, data ) );
  713.                 (void)AEDisposeDesc( &fakeReply );
  714.                 ODDeleteObject( odreply );
  715.             }
  716.             else
  717.             {
  718.                 *data = userToken;
  719.             }
  720.         CATCH_ALL
  721.             (void)AEDisposeDesc( &userToken );
  722.             (void)AEDisposeDesc( &tmpDesc );
  723.             (void)AEDisposeDesc( &fakeReply );
  724.             (void)AEDisposeDesc( &fakeAEVT );
  725.             ODDeleteObject( odaevt );
  726.             ODDeleteObject( odreply );
  727.             RERAISE;
  728.         ENDTRY
  729.     }
  730.     else
  731.     {
  732.         THROW_IF_ERROR( ODDescToAEDesc( obj, data ) );
  733.     }
  734. }
  735.  
  736. static short BitwiseCompare( AEDesc* data1, AEDesc* data2 )
  737. {
  738.     unsigned char* ptr1 = (unsigned char*)*(data1->dataHandle);
  739.     unsigned char* ptr2 = (unsigned char*)*(data2->dataHandle);
  740.     long len1 = GetHandleSize(data1->dataHandle);
  741.     long len2 = GetHandleSize(data2->dataHandle);
  742.     
  743.     short result = 0;
  744.     while ( len1 && len2 )
  745.     {
  746.         if ( *ptr1 == *ptr2 )
  747.         {
  748.             ++ptr1; ++ptr2;
  749.             --len1; --len2;
  750.             continue;
  751.         }
  752.         result = *ptr1 > *ptr2 ? 1 : -1;
  753.         break;
  754.     }
  755.     // if we're here it's 'cause we ran off one end.
  756.     if ( result == 0 )
  757.     {
  758.         if ( len1 )
  759.             result = 1;
  760.         else if ( len2 )
  761.             result = -1;
  762.         else
  763.             result = 0;
  764.     }
  765.     return result;
  766. }
  767.  
  768. static short CompareDescs( AEDesc* data1, AEDesc* data2 )
  769. {
  770.     typedef long doubleLong[2];
  771.     short result = 0;
  772.     if ( data1->descriptorType != data2->descriptorType )
  773.     {
  774.         WARN( "CompareDescs: coercion should have been done already" );
  775.         THROW( errAECoercionFail );
  776.     }
  777.     else
  778.         switch( data1->descriptorType )
  779.         {
  780.             case typeChar:
  781.                 // <eeh> need to lowercase if possible.  Really ought to
  782.                 // check out the considerations flags, but they're probably
  783.                 // not accessible.
  784.                 // $$$$$ not yet tested on Kanji system.  For instance, double-byte
  785.                 // representations of Roman characters should be equal to their
  786.                 // single-byte equivalents.  Are they using this code?
  787.                 HLock(data1->dataHandle);
  788.                 HLock(data2->dataHandle);
  789.                 long str1Len = GetHandleSize( data1->dataHandle );
  790.                 long str2Len = GetHandleSize( data2->dataHandle );
  791.                 UppercaseText( *data1->dataHandle, str1Len, smCurrentScript );
  792.                 UppercaseText( *data2->dataHandle, str2Len, smCurrentScript );
  793.                 result = CompareText( *data1->dataHandle, *data2->dataHandle,
  794.                         str1Len, str2Len, NULL );
  795.                 break;
  796.             case typeLongInteger:        // signed, so bitwise doesn't work!
  797.                 signed long l1 = *(signed long*)*(data1->dataHandle);
  798.                 signed long l2 = *(signed long*)*(data2->dataHandle);
  799.                 result = (l1 == l2)? 0 : l1 > l2? 1 : -1;
  800.                 break;
  801.             case typeType:
  802.             case typeEnumeration:
  803.             case typeLongDateTime:
  804.             case typeBoolean:
  805.             default:        // <eeh> should unknown types throw an error
  806.                             // instead?
  807.                 result = BitwiseCompare( data1, data2 );
  808.                 break;
  809.         }
  810.     return result;
  811. }
  812.  
  813. #if 0
  814. // This isn't being used right now but probably will be later.
  815. void GetUserTokenFromDesc( Environment* ev, ODNameResolver* resolver,
  816.         AEDesc* tokenWrapper, AEDesc* resultDesc )
  817. {
  818.     ODOSLToken* odWrapper = new ODOSLToken();
  819.     THROW_IF_NULL(odWrapper);
  820.     odWrapper->InitODOSLToken(ev);
  821.     THROW_IF_ERROR( AEDescToODDesc( tokenWrapper, odWrapper ) );
  822.     WASSERT( resolver->IsODToken( ev, odWrapper ) );
  823.     ODDesc* userTokenWrapper = resolver->GetUserToken( ev, odWrapper );
  824.     THROW_IF_ERROR( ODDescToAEDesc( userTokenWrapper, resultDesc ) );
  825.     ODDeleteObject( odWrapper );
  826. }
  827.  
  828. static ODBoolean ContainerRepresentsPart( Environment* ev,
  829.         ODNameResolver* resolver, ODOSLToken* container )
  830. {
  831.     ODBoolean result = kODFalse;
  832.     if ( resolver->IsODToken( ev, container ) )
  833.     {
  834.         ODDesc* tmpToken = resolver->GetUserToken(ev, container);
  835.         ODDescType tokenType = tmpToken->GetDescType(ev);
  836.         // (NULL token is not acceptable here)
  837.         // <eeh> putting NULL back in because this breaks "every part whose"
  838.         // when the root isn't scriptable.
  839.         if ( (tokenType == kODStandardPartTokenType) || (tokenType == typeNull) )
  840.             result = kODTrue;
  841.         else if ( tokenType == typeAEList )
  842.             THROW( kODErrUndefined );
  843.         else
  844.         {
  845.             AEDesc token;
  846.             THROW_IF_ERROR( ODDescToAEDesc( tmpToken, &token ) );
  847.             if ( CanBeStandardPartToken( &token ) )
  848.                 result = kODTrue;
  849.             (void)AEDisposeDesc( &token );
  850.         }        
  851.     }
  852.     return result;
  853. }
  854. #endif
  855.  
  856.